/*
 * Copyright (c) 2010, Christian Lerche
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Christian Lerche <christian.lerche@uni-rostock.de>
 *
 */

#ifndef COMMON_H_
#define COMMON_H_

#include <stdint.h>
#include <string.h>

#define SET_FLAG(a, b)       a|=b
#define CLR_FLAG(a, b)       a&=~b
#define IS_SET_FLAG(a, b)    a&b

extern const char whitespaces_and_colon[];
#define whitespaces_and_colon_len          5
#define whitespaces 		               whitespaces_and_colon
#define whitespaces_len                    4

/*common functions*/
#define ignore_whitesp(p, p_end, p_new)               ignore_c_arr(p, p_end, whitespaces, whitespaces_len ,p_new)
void itoa2(int n, char s[]);
int ignore_c_arr(char* p, char* p_end, const char* c, int c_len, char** p_new);
int remove_whitesp_beg_end(char** buf, int *buf_len);

/* xml tag type definitions */
#define XML_TAG_TYPE_START   0
#define XML_TAG_TYPE_END     1
#define XML_TAG_TYPE_EMPTY   2

struct xml_tag_s {
    char* namespace;
    char* tag_name;
    uint8_t tag_type; //--> xml tag type definitions
};

/* defines for xml_next_tag() error_check option
 * e.g. xml_next_tag(... , XML_NEXT_TAG_ERR_IF_EMPTY | XML_NEXT_TAG_ERR_IF_CLOSE
 * !returns errors immediately! */
#define XML_NEXT_TAG_ERR_IF_EMPTY         0x01
#define XML_NEXT_TAG_ERR_IF_CLOSE         0x02
#define XML_NEXT_TAG_ERR_IF_NOT_CLOSE     0x04

/* parses the next xml tag, xml_tag could be NULL (--> no tag parsing)
 * tag_type CANNOT be NULL */
int xml_next_tag(char* p, char* p_end, struct xml_tag_s* xml_tag, uint8_t* tag_type, uint8_t error_check, char** p_new);
/* can be called after xml_next_tag() to skip over the complete content (this also includes sub xml structures)*/
int xml_skip_tag_content(char* p, char* p_end, char** p_new);
/* Get the content as null terminated string, NULL if empty
 * e.g.: " 12 <..." --> "12\0"*/
char* xml_cont_as_str(char* p, char* msg_end);
/* char based parsing functions */
int find_next_c(char* p, char* p_end, char c, char** p_new);
char* parse_to(const char* src, const char* find, int src_len, int find_len);

/* -------------- stack implementation --------------- */
struct stack_s {
    char* mem;
    char* end;
    char* top;
};
void stack_init(struct stack_s *stack, char* mem, int len);
void stack_push(struct stack_s *stack, int len);
char* stack_pop(struct stack_s *stack, int len);
char* stack_memdup(struct stack_s *stack, char* buf, int len);
#define stack_free(stack) ((stack)->top = (stack)->mem)

#endif /* COMMON_H_ */
